package ie.dkit.semanticPhotoWeb.client.panels.tag;

import java.util.List;

import ie.dkit.semanticPhotoWeb.client.ClientServerConnectorAsync;
import ie.dkit.semanticPhotoWeb.client.dtos.AlbumDTO;
import ie.dkit.semanticPhotoWeb.client.dtos.ImageDTO;
import ie.dkit.semanticPhotoWeb.client.dtos.TagDTO;
import ie.dkit.semanticPhotoWeb.client.panels.UserOverviewPanel;
import ie.dkit.semanticPhotoWeb.client.panels.album.AlbumPanel;
import ie.dkit.semanticPhotoWeb.client.panels.photo.PhotoPanel;
import ie.dkit.semanticPhotoWeb.client.tools.AsyncCallbackAdapter;

import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.MessageBox.PromptCallback;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.layout.HorizontalLayout;

public class TagPanel extends Panel {

	private class TagCallback extends AsyncCallbackAdapter {

		private boolean editable;

		public TagCallback(boolean editable) {
			this.editable = editable;
		}

		public void onSuccess(Object result) {
			showTags((List) result, editable);
		}

	}

	private class Tag extends Panel {

		private TagDTO m_CurrenTagDTO;

		public Tag(TagDTO tagDTO) {
			m_CurrenTagDTO = tagDTO;
			setBorder(false);
			Panel panel = new Panel();
			panel.setBorder(false);
			panel.setLayout(new HorizontalLayout(2));
			panel.add(new Label(tagDTO.tagString));
			panel.add(new Button("X", new ButtonListenerAdapter() {
				public void onClick(Button button, EventObject e) {
					MessageBox.wait("deleting Tag");
					m_ClientServerConnectorAsync.deleteTag(m_CurrenTagDTO,
							new AsyncCallbackAdapter() {
								public void onSuccess(Object result) {
									MessageBox.hide();
									getTags(m_CurrentImageDTO);
								}
							});
				}
			}));
			add(panel);
		}
	}

	private ClientServerConnectorAsync m_ClientServerConnectorAsync;

	private ImageDTO m_CurrentImageDTO;

	public TagPanel(ClientServerConnectorAsync clientServerConnectorAsync,
			UserOverviewPanel albumOverviewPanel) {
		m_ClientServerConnectorAsync = clientServerConnectorAsync;
		setTitle("TagCloud");
		setAutoScroll(true);
		setCollapsible(true);
		if (albumOverviewPanel.getCurrentUsername() != null) {
			getTags(albumOverviewPanel.getCurrentUsername());
		} else {
			getTags();
		}
	}

	public TagPanel(ClientServerConnectorAsync clientServerConnectorAsync,
			AlbumPanel albumPanel) {
		m_ClientServerConnectorAsync = clientServerConnectorAsync;
		setTitle("TagCloud");
		setAutoScroll(true);
		setCollapsible(true);
		getTags(albumPanel.getCurrentAlbumDTO());
	}

	public TagPanel(ClientServerConnectorAsync clientServerConnectorAsync,
			PhotoPanel photoPanel) {
		m_ClientServerConnectorAsync = clientServerConnectorAsync;
		m_CurrentImageDTO = photoPanel.getCurrentImageDTO();
		setTitle("Tags");
		setCollapsible(true);
		setAutoScroll(true);
		setHeight(70);
		getTags(m_CurrentImageDTO);
	}

	private void getTags() {
		m_ClientServerConnectorAsync.getUserTags(new TagCallback(false));
	}

	private void getTags(String username) {
		m_ClientServerConnectorAsync.getUserTags(username, new TagCallback(
				false));
	}

	private void getTags(AlbumDTO albumDTO) {
		m_ClientServerConnectorAsync.getTags(albumDTO, new TagCallback(false));
	}

	private void getTags(ImageDTO imageDTO) {
		m_ClientServerConnectorAsync.getTags(imageDTO, new TagCallback(true));
	}

	private void showTags(List tagDTOs, boolean editable) {
		if (editable) {
			showEditableTagView(tagDTOs);
		} else {
			showTagCloud(tagDTOs);
		}

	}

	private void showEditableTagView(List tagDTOs) {
		clear();
		for (int i = 0; i < tagDTOs.size(); i++) {
			add(new Tag((TagDTO) tagDTOs.get(i)));
		}
		add(new Button("Add Tag", new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				MessageBox.prompt("Add new Tag", "Please insert a new Tag",
						new PromptCallback() {
							public void execute(String btnID, String text) {
								MessageBox.wait("Please wait... tagging");
								if (btnID.equals("ok")) {
									m_ClientServerConnectorAsync.addTag(
											m_CurrentImageDTO,
											new TagDTO(text),
											new AsyncCallbackAdapter() {
												public void onSuccess(
														Object result) {
													MessageBox.hide();
													getTags(m_CurrentImageDTO);
												}
											});
								} else {
									MessageBox.hide();
								}
							}
						});
			}
		}));
		doLayout();
	}

	private void showTagCloud(List tagDTOs) {
		if (tagDTOs.size() <= 0) {
			return;
		}
		clear();
		int min = 0, max = 0;
		TagDTO currentTag;
		for (int i = 0; i < tagDTOs.size(); i++) {
			currentTag = (TagDTO) tagDTOs.get(i);
			if (i == 0) {
				min = max = currentTag.weight;
			}
			if (currentTag.weight < min) {
				min = currentTag.weight;
			} else if (currentTag.weight > max) {
				max = currentTag.weight;
			}
		}
		int diff = max - min;
		int distribution = diff / 3;
		String content = "";
		for (int i = 0; i < tagDTOs.size(); i++) {
			if (i % 10 == 0) {
				content += "<br />";
			}
			currentTag = (TagDTO) tagDTOs.get(i);
			content += "&nbsp;&nbsp;&nbsp;&nbsp;"
					+ getFontString(currentTag, min, max, distribution);
		}
		add(new HTML(content));
		doLayout();
	}

	private String getFontString(TagDTO tagDTO, int min, int max,
			int distribution) {
		int weigth = tagDTO.weight;
		if (weigth == -1) {
			return surroundWithFontString(tagDTO.tagString, "-3", "green");
		}
		if (weigth == min) {
			return surroundWithFontString(tagDTO.tagString, "-5", "black");
		} else if (weigth == max) {
			return surroundWithFontString(tagDTO.tagString, "10", "red");
		} else if (weigth > ((min + (distribution * 2)))) {
			return surroundWithFontString(tagDTO.tagString, "5", "blue");
		} else if (weigth > (min + distribution)) {
			return surroundWithFontString(tagDTO.tagString, "0", "yellow");
		} else {
			return surroundWithFontString(tagDTO.tagString, "-3", "green");
		}
	}

	private String surroundWithFontString(String stringToSurround,
			String fontSize, String color) {
		return "<font size=\"" + fontSize + "\" color=\"" + color + "\">"
				+ stringToSurround + "</font>";
	}
}
